package mapControl;


import net.datastructures.Vertex;
import powerUp.PowerUp;
import wallFactory.builders.WallBox;
import ED.GraphImp;

import com.jme.math.Vector3f;

import elementos.Bomba;
import elementos.Player;
import enemies.Enemy;

public abstract class MapControl {

	public void showMap() {
		for (int row = 0; row < wide; ++row) {
			for (int col = 0; col < hight; ++col) {
				if (map[col][row].getNonDesWallBox() != null)
					System.out.print("x");
				else if (map[col][row].getDesWallBox() != null)
					System.out.print("o");
				else
					System.out.print(" ");

			}
			System.out.print("\n");
		}

	}

	int wide;
	int hight;
	int tilesize;
	Celda[][] map;
	ContadorBombas contadorBombas;
	GraphImp<Celda, Integer> graph;
	private Vertex<Celda>[][] mapg;
	private Vertex<Celda>[][] map4g;
	private GraphImp<Celda, Integer> graph4g;
	
	protected float speed = 30;
	protected int bombPower = 3;

	
	

	public Vertex<Celda>[][] getMapg() {
		return mapg;
	}	public Vertex<Celda>[][] getMap4g() {
		return map4g;
	}

	
	public MapControl(int wide, int hight, int tilesize) {
		this.wide = wide;
		this.hight = hight;
		this.tilesize = tilesize;
		this.contadorBombas = new ContadorBombas(3);
		map = new Celda[wide][hight];
	

	}

	public Celda getCelda(int row, int col) {
		return map[row][col];
	}

	public int getWide() {
		return wide;
	}

	public void setWide(int wide) {
		this.wide = wide;
	}

	public int getHight() {
		return hight;
	}

	public void setHight(int hight) {
		this.hight = hight;
	}

	public int getTilesize() {
		return tilesize;
	}

	public void setTilesize(int tilesize) {
		this.tilesize = tilesize;
	}

	public ContadorBombas getContadorBombas() {
		return contadorBombas;
	}

	public class ContadorBombas {
		private int cantidadBombas;
		private int cantidadInstaladas;

		public ContadorBombas(int i) {
			cantidadBombas = i;
		}

		public void detonarBomba() {
			cantidadInstaladas--;
		};

		public int getCantidadBombas() {
			return cantidadBombas;
		}

		public int getCantidadInstaladas() {
			return cantidadInstaladas;
		}

		public boolean hayBombas() {
			return cantidadInstaladas < cantidadBombas;
		}

		public void instalarBomba() {
			cantidadInstaladas++;
		}

		public void setCantidadBombas(int cantidadBombas) {
			this.cantidadBombas = cantidadBombas;
		}

		public void incBombas() {
			cantidadBombas++;
			
		}

	}

	public void removeWall(WallBox wall) {

		map[wall.getRow()][wall.getCol()].setDesWallBox(null);

	}

	public void addNonDesWall(WallBox wall) {

		map[wall.getRow()][wall.getCol()].setNonDesWallBox(wall);
	}

	public void addDesWall(WallBox wall) {

		map[wall.getRow()][wall.getCol()].setDesWallBox(wall);

	}

	public void addBomb(Bomba bomb) {

		map[bomb.getRow()][bomb.getCol()].setBomba(bomb);

	}

	public void movePlayer(Player player) {
		map[player.getRow()][player.getCol()].setPlayer(player);
	}

	public void removeBomb(Bomba bomb) {

		map[bomb.getRow()][bomb.getCol()].setBomba(null);

	}

	public Vector3f getTraslation(int row, int col) {
		Vector3f vector = new Vector3f((row * tilesize) - (tilesize / 2), 0,
				(col * tilesize) - (tilesize / 2));
		return vector;
	}

	public Vector3f getTraslationCentrada(int row, int col) {
		Vector3f vector = new Vector3f((row * tilesize), 0, (col * tilesize));
		return vector;
	}

	public int getRow(Vector3f traslation) {
		return (int) ((traslation.x + (tilesize / 2)) / tilesize);
	}

	public int getCol(Vector3f traslation) {
		return (int) ((traslation.z + (tilesize / 2)) / tilesize);

	}

	public boolean isEmpty(int row, int col) {
		return map[row][col].isEmpty();
	}

	public void crearCelda(int row, int col) {
		map[row][col] = new Celda(row, col);
	}

	@SuppressWarnings("unchecked")
	public void buildGraph() {

		mapg = new Vertex[wide][hight];
		map4g = new Vertex[wide][hight];
		graph = new GraphImp<Celda, Integer>();
		graph4g = new GraphImp<Celda, Integer>();

		for (int row = 0; row < wide; row++) {
			for (int col = 0; col < hight; col++) {
				mapg[row][col] = graph.insertVertex(map[row][col]);
				map4g[row][col] = graph4g.insertVertex(map[row][col]);
			}
		}

		for (int row = 0; row < wide; row++) {
			for (int col = 0; col < hight; col++) {
				if (mapg[row][col].element().isEmpty()) {
					if (col > 0)
						if (mapg[row][col - 1].element().isEmpty())

							graph.insertEdge(mapg[row][col],
									mapg[row][col - 1], 1);
					if (col < wide - 1)
						if (mapg[row][col + 1].element().isEmpty())

							graph.insertEdge(mapg[row][col],
									mapg[row][col + 1], 1);
					if (row > 0)
						if (mapg[row - 1][col].element().isEmpty())

							graph.insertEdge(mapg[row][col],
									mapg[row - 1][col], 1);
					if (row < hight - 1)
						if (mapg[row + 1][col].element().isEmpty())

							graph.insertEdge(mapg[row][col],
									mapg[row + 1][col], 1);
				}
				
				if (map4g[row][col].element().isEmpty4g()) {
					if (col > 0)
						if (map4g[row][col - 1].element().isEmpty4g())

							graph4g.insertEdge(map4g[row][col],
									map4g[row][col - 1], 1);
					if (col < wide - 1)
						if (map4g[row][col + 1].element().isEmpty4g())

							graph4g.insertEdge(map4g[row][col],
									map4g[row][col + 1], 1);
					if (row > 0)
						if (map4g[row - 1][col].element().isEmpty4g())

							graph4g.insertEdge(map4g[row][col],
									map4g[row - 1][col], 1);
					if (row < hight - 1)
						if (map4g[row + 1][col].element().isEmpty4g())

							graph4g.insertEdge(map4g[row][col],
									map4g[row + 1][col], 1);
				}
				
				
				
				
				
			}
		}

	

	}

	public void addPlayer(Player player) {
		map[player.getRow()][player.getCol()].setPlayer(player);

	}

	public GraphImp<Celda, Integer> getGraph() {
		return graph;

	}

	public GraphImp<Celda, Integer> getGraph4g() {
		return graph4g;

	}
	public void addPowerUp(PowerUp powerUp) {
		map[powerUp.getRow()] [powerUp.getCol()].setPowerUp(powerUp);
		
	}
	public void removePowerUp(PowerUp powerUp) {
		map[ powerUp.getRow()] [ powerUp.getCol()].setPowerUp(null);
	}
	public void removeEnemy(Enemy enemy) {
		map[enemy.getRow()][enemy.getCol()].removeEnemy(enemy);
			
	}
	
}
